#ifndef _LZE_H
#define _LZE_H

//common.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>

//保证对应大小对齐
#define auto_nmemb(a, b) ({ \
		typeof(a) _a = (a) , _b = (b); \
		( (a) < (b) ) ?	(a) : (b) ;	\
	})

//////////////////////////////////////////////////////WINDOWS
#if _WIN32 || _WIN64
//#define MAX_BITS 12
#define MAX_BITS 20
#define TABLE_SIZE (1 << MAX_BITS)
#define CLEAR_CODE 256
#define END_CODE 257
//因为无法auto_update，并且没找到原因所在，所以这里我直接手动使INIT_BITS == MAX_BITS了。
//#define INIT_BITS 9
#define INIT_BITS 20

/*基于需求，启用 #pragma pack()
*/
//#pragma pack(1)
typedef struct
{
	int prefix;
	int next[256];
} CompressDict;	//压缩字典
typedef struct
{
	int prefix;
	unsigned char c;
} DecompressDict; //解压字典
typedef struct
{
	FILE *fp;
	unsigned int buffer;
	int bit_count;
} BitWriter, BitReader; //位写入器、位读取器
//#pragma pack()

/*
位写入器初始化 */
void bit_writer_init(BitWriter *bw, FILE *fp);
/*
精确位写入实现 */
void write_bits(BitWriter *bw, int code, int bits);
/*
强制刷新剩余位 */
void flush_bits(BitWriter *bw);
/*
位读取器初始化 */
void bit_reader_init(BitReader *br, FILE *fp);
/*
精确位读取实现 */
int read_bits(BitReader *br, int bits);
/*
LZW压缩核心算法*/
long lzw_compress(FILE *input, FILE *output);
/*
LZW解压核心算法 */
void lzw_decompress(FILE *input, FILE *output);
/////////////////////////////////////////////////Windows

////////////////////////////////////////////////////LINUX
#else //LINUX
/* TODO (dmsj#2#): TABLE_SIZE 等value为定值，不利于处
                   理突发情况，[如path过长，致使栈溢
                   出等问题]，需使用dynastic value
                   replace，后期改进 */
#define MAX_BITS    12
#define TABLE_SIZE  4096

typedef struct
{
	int prefix;
	int next;
} LZWEntry;

void lzw_compress(FILE *, FILE *);
void lzw_decompress(FILE *, FILE *);

#endif 	//Different case in Linux & Windows .

#endif /*_LZE_H*/
